package uk.co.hs.util;

import java.util.ArrayList;
import java.util.List;

/**
 * QueryStringBindValueCombo.
 */
public class QueryStringBindValueCombo
implements Comparable<QueryStringBindValueCombo>
{
  private String mQueryString;
  private List<Object> mValues;
  private List<Class< ? >> mClassTypes;
  private String mJoinType;

  public static final String AND = "AND";
  public static final String OR = "OR";

  /**
   * Constructor.
   *
   * @param aQueryString Query String.
   */
  public QueryStringBindValueCombo(String aQueryString)
  {
    mQueryString = aQueryString;
  }

  /**
   * Constructor.
   *
   * @param aQueryString Query String.
   * @param aValues Query Value.
   * @param aClassTypes List of the Class Types.
   */
  public QueryStringBindValueCombo(String aQueryString,
                                   List<Object> aValues,
                                   List<Class< ? >> aClassTypes)
  {
    mQueryString = aQueryString;
    mValues = aValues;
    mClassTypes = aClassTypes;
  }

  /**
   * Constructor.
   *
   * @param aQueryString Query String.
   * @param aValue Query Value.
   * @param aClassType Class Type.
   */
  public QueryStringBindValueCombo(String aQueryString,
                                   Object aValue,
                                   Class< ? > aClassType)
  {
    mQueryString = aQueryString;
    mValues = new ArrayList<Object>();
    mValues.add(aValue);
    mClassTypes = new ArrayList<Class< ? >>();
    mClassTypes.add(aClassType);
  }

  /**
   * @return the queryString
   */
  public String getQueryString()
  {
    return mQueryString;
  }

  /**
   * @param aQueryString the queryString to set
   */
  public void setQueryString(String aQueryString)
  {
    mQueryString = aQueryString;
  }

  /**
   * @return the values
   */
  public List<Object> getValues()
  {
    return mValues;
  }

  /**
   * @param aValues the values to set
   */
  public void setValues(List<Object> aValues)
  {
    mValues = aValues;
  }

  /**
   * @return the classTypes
   */
  public List<Class< ? >> getClassTypes()
  {
    return mClassTypes;
  }

  /**
   * @param aClassTypes the classTypes to set
   */
  public void setClassTypes(List<Class< ? >> aClassTypes)
  {
    mClassTypes = aClassTypes;
  }

  /**
   * @return the joinType
   */
  public String getJoinType()
  {
    return mJoinType;
  }

  /**
   * @param aJoinType the joinType to set
   */
  public void setJoinType(String aJoinType)
  {
    mJoinType = aJoinType;
  }

  /* (non-Javadoc)
   * @see java.lang.Comparable#compareTo(java.lang.Object)
   */
  @Override
  public int compareTo(QueryStringBindValueCombo aCompareCombo)
  {
    if (aCompareCombo.getClassTypes().contains(String.class)
        && (aCompareCombo.getQueryString().contains("=")
        && !aCompareCombo.getQueryString().contains("!"))
            || (aCompareCombo.getQueryString().contains("LIKE")
                && !aCompareCombo.getQueryString().contains("NOT")))
    {
      if (aCompareCombo.getJoinType().equals(AND) && this.getJoinType().equals(OR))
      {
        //AND comes before OR
        return 1;
      }
      else if (aCompareCombo.getJoinType().equals(OR) && this.getJoinType().equals(AND))
      {
        return -1;
      }
      else if (aCompareCombo.getJoinType().equals(OR) && this.getJoinType().equals(OR))
      {
          return getQueryItem().compareTo(aCompareCombo.getQueryItem());
      }
    }
    return 1;
  }

  public String getQueryItem()
  {
    String[] queryTokens = getQueryString().split("=");
    if (queryTokens.length > 1)
    {
      if (!queryTokens[0].contains("!"))
      {
        return queryTokens[0];
      }
    }
    else if (queryTokens.length == 1)
    {
      queryTokens = getQueryString().split("LIKE");
      if (queryTokens.length > 1)
      {
        if (!queryTokens[0].contains("NOT"))
        {
          return queryTokens[0];
        }
      }
    }
    return getQueryString();
  }
}
